package org.advanced.expand;

/**
 * @author John.zhang
 * @version Id: TransAccountA, v 1.0 2020/12/11 17:18 ZhiYong Exp $
 * 破坏死锁(破坏不释放的问题)
 */
public class TransAccountA implements Runnable {

    private Account fromAccount;

    private Account toAccount;

    private int amount;

    Allocator allocator;

    public TransAccountA(Account fromAccount, Account toAccount, int amount, Allocator allocator) {
        this.fromAccount = fromAccount;
        this.toAccount = toAccount;
        this.amount = amount;
        this.allocator = allocator;
    }

    @Override
    public void run() {
        while (true) {
            if (allocator.apply(fromAccount, toAccount)) {
                try {
                    synchronized (fromAccount) {
                        synchronized (toAccount) {
                            if (fromAccount.getBalance() >= amount) {
                                fromAccount.debit(amount);
                                toAccount.credit(amount);
                            }
                        }
                        System.out.println(fromAccount.getAccountName() + "-" + fromAccount.getBalance());
                        System.out.println(toAccount.getAccountName() + "-" + toAccount.getBalance());
                    }
                } finally {
                    allocator.free(fromAccount, toAccount);
                }
            }

        }
    }


    public static void main(String[] args) {
        Account fromAccount = new Account("张三", 100000);
        Account toAccount = new Account("李四", 200000);

        Allocator allocator = new Allocator();
        Thread threadA = new Thread(new TransAccountA(fromAccount, toAccount, 1,allocator));
        Thread threadB = new Thread(new TransAccountA(toAccount, fromAccount, 1,allocator));
        threadA.start();
        threadB.start();
    }

}
